﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YRevitJig;

namespace YArchitech.Plumbing.ExtendElementSet
{
	public class StretchElementsJig : XUiJigBase
	{
		public List<YJKLine> OutSideLines { get; set; }

		public List<YJKLine> InSideLines { get; set; }

		public XYZ StartPoint { get; set; }

		public XYZ MovingVector { get; set; }

		public UIDocument UIDoc { get; set; }

		public StretchElementsJig(UIDocument uiDoc) : base(uiDoc)
		{
			this.UIDoc = uiDoc;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (!this.m_ptCur.IsEmpty && paintEventArgs != null && this.StartPoint != null)
			{
				try
				{
					if (this.ElementSetIsMovable(this.OutSideLines))
					{
						XYZ xyz = base.Client2Revit(this.m_ptCur);
						XYZ xyz2 = new XYZ(xyz.X, xyz.Y, this.StartPoint.Z);
						MovingDirection movingDirection = MovingDirection.undefined;
						XYZ xyz3;
						if (this.HorizontalLine == null && this.VerticalLine == null)
						{
							xyz3 = this.GetAxisPoint(this.UIDoc, xyz2, this.StartPoint);
						}
						else
						{
							xyz3 = this.GetHoriOrVertPoint(this.UIDoc, xyz2, this.StartPoint, ref movingDirection);
						}
						if (xyz3 != null)
						{
							xyz2 = xyz3;
						}
						this.MovingVector = xyz2 - this.StartPoint;
						XGraphics g = new XGraphics(paintEventArgs.Graphics, base.JigPen);
						if (this.OutSideLines != null)
						{
							foreach (YJKLine YJKLine in this.OutSideLines)
							{
								XYZ point = YJKLine.StartPoint;
								if (movingDirection == MovingDirection.Horizontal && this.HorizontalLine != null && this.HorizontalLine.IsVertical(YJKLine.Line))
								{
									point = YJKLine.StartPoint.Add(this.MovingVector);
								}
								if (movingDirection == MovingDirection.Vertical && this.VerticalLine != null && this.VerticalLine.IsVertical(YJKLine.Line))
								{
									point = YJKLine.StartPoint.Add(this.MovingVector);
								}
								XYZ point2 = YJKLine.EndPoint.Add(this.MovingVector);
								XLine2D xline2D = new XLine2D(base.Revit2Client(point), base.Revit2Client(point2));
								xline2D.Draw(g);
							}
						}
						if (this.InSideLines != null)
						{
							foreach (YJKLine YJKLine2 in this.InSideLines)
							{
								XYZ point = YJKLine2.StartPoint.Add(this.MovingVector);
								XYZ point2 = YJKLine2.EndPoint.Add(this.MovingVector);
								XLine2D xline2D = new XLine2D(base.Revit2Client(point), base.Revit2Client(point2));
								xline2D.Draw(g);
							}
						}
					}
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
		}

		public void GetHoriAndVertLines()
		{
			try
			{
				if (this.OutSideLines != null && this.OutSideLines.Count > 0)
				{
					this.HorizontalLine = this.OutSideLines[0];
					foreach (YJKLine YJKLine in this.OutSideLines)
					{
						if (this.HorizontalLine.IsVertical(YJKLine.Line))
						{
							this.VerticalLine = YJKLine;
							break;
						}
					}
					if (this.VerticalLine == null)
					{
						this.VerticalLine = this.GetNormalVecLine(this.HorizontalLine);
					}
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		protected bool ElementSetIsMovable(List<YJKLine> lineSet)
		{
			bool flag = true;
			if (lineSet != null && lineSet.Count > 0)
			{
				YJKLine YJKLine = lineSet[0];
				foreach (YJKLine YJKLine2 in lineSet)
				{
					flag &= (YJKLine.IsParallel(YJKLine2.Line) || YJKLine.IsVertical(YJKLine2.Line));
				}
			}
			return flag;
		}

		protected XYZ GetHoriOrVertPoint(UIDocument uiDoc, XYZ ptUser, XYZ ptOrigin, ref MovingDirection directron)
		{
			if (ptUser.DistanceTo(ptOrigin) < 0.0032808398950131233)
			{
				return null;
			}
			if (this.HorizontalLine != null)
			{
				Line line = Line.CreateUnbound(ptOrigin, this.HorizontalLine.EndPoint - this.HorizontalLine.StartPoint);
				XYZ xyzpoint = line.Project(ptUser).XYZPoint;
				if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.78539816339744828)
				{
					directron = MovingDirection.Horizontal;
					return xyzpoint;
				}
			}
			if (this.VerticalLine != null)
			{
				Line line = Line.CreateUnbound(ptOrigin, this.VerticalLine.EndPoint - this.VerticalLine.StartPoint);
				XYZ xyzpoint = line.Project(ptUser).XYZPoint;
				if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.78539816339744828)
				{
					directron = MovingDirection.Vertical;
					return xyzpoint;
				}
			}
			return null;
		}

		protected XYZ GetAxisPoint(UIDocument uiDoc, XYZ ptUser, XYZ ptOrigin)
		{
			if (ptUser.DistanceTo(ptOrigin) < 0.0032808398950131233)
			{
				return null;
			}
            Autodesk.Revit.DB.View activeView = uiDoc.ActiveView;
			Line line = Line.CreateUnbound(ptOrigin, activeView.RightDirection);
			XYZ xyzpoint = line.Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			line = Line.CreateUnbound(ptOrigin, activeView.UpDirection);
			xyzpoint = line.Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			Transform transform = Transform.CreateRotation(activeView.ViewDirection, 0.78539816339744828);
			XYZ xyz = transform.OfVector(activeView.RightDirection);
			line = Line.CreateUnbound(ptOrigin, xyz);
			xyzpoint = line.Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			xyz = transform.OfVector(activeView.UpDirection);
			line = Line.CreateUnbound(ptOrigin, xyz);
			xyzpoint = line.Project(ptUser).XYZPoint;
			if (xyzpoint.DistanceTo(ptOrigin) > 0.1 && this.Get3PtAngle(xyzpoint, ptOrigin, ptUser) < 0.052359877559829883)
			{
				return xyzpoint;
			}
			return null;
		}

		public YJKLine GetNormalVecLine(YJKLine originalLine)
		{
			XYZ xyz = originalLine.EndPoint - originalLine.StartPoint;
			XYZ xyz2 = this.StartPoint.Add(xyz / 2.0);
			XYZ xyz3 = new XYZ(0.0, 0.0, 1.0);
			XYZ xyz4 = xyz3.CrossProduct(xyz);
			XYZ end = xyz2.Add(xyz4);
			return new YJKLine(xyz2, end);
		}

		protected double Get3PtAngle(XYZ pt1, XYZ ptOrigin, XYZ pt2)
		{
			XYZ xyz = pt1 - ptOrigin;
			XYZ xyz2 = pt2 - ptOrigin;
			return xyz.AngleTo(xyz2);
		}

		protected YJKLine HorizontalLine;

		protected YJKLine VerticalLine;
	}
}
